#ifndef THESCT_H
#define THESCT_H

/****************************************
 * Filename: thesct.h
 * Author  : xy_god
 * E-Mail  : xy_god@thesct.net
 * Datetime: 2017-05-15 08:53
 * Comment :
 *     该文件描述了TheSCT(结构化意识论)
 * 思想相关的数据结构。
 ****************************************/

#include <cstddef>
#include <math.h>

#include "cvisionmatterelementset.h"

typedef struct tagDELTA
{
    bool bValid;    // 该分量变化是否有效：true，有效；false，无效。
    int  iSign;     // 变化方向标志：1，增大；-1;，减小；0，不变，iMin == iMax。
    int  iMin;      // 变化的最小范围，取负，则无限小。
    int  iMax;      // 变化的最大范围，取负，则无限大。

} DELTA, *PDELTA;
typedef struct tagDELTAS
{
    DELTA deltaR; // R分量变化
    DELTA deltaG; // G分量变化
    DELTA deltaB; // B分量变化
    DELTA deltaY; // Y分量变化
} DELTAS, *PDELTAS;

typedef struct tagPOINT       // 同一物点集中的点
{
    int x;                    // 水平坐标
    int y;                    // 纵向坐标
    int n;                    // 该点序号
    int iMaxNeighbour;        // 最大相邻点数目
    int iCurNeighbour;        // 当前已经发现的相邻点数

    int b_up;                 // 上一点是否存在或者有效，-1：不存在;0：无效;1：有效;
    struct tagPOINT *up;      // 上一点

    int b_down;               // 下一点是否存在或者有效，-1：不存在;0：无效;1：有效;
    struct tagPOINT *down;    // 下一点

    int b_left;               // 左一点是否存在或者有效，-1：不存在;0：无效;1：有效;
    struct tagPOINT *left;    // 左一点

    int b_right;              // 右一点是否存在或者有效，-1：不存在;0：无效;1：有效;
    struct tagPOINT *right;   // 右一点

    int b_lu;                 // 左上一点是否存在或者有效，-1：不存在;0：无效;1：有效;
    struct tagPOINT *lu;      // 左上一点

    int b_ld;                 // 左下一点是否存在或者有效，-1：不存在;0：无效;1：有效;
    struct tagPOINT *ld;      // 左下一点

    int b_ru;                 // 右上一点是否存在或者有效，-1：不存在;0：无效;1：有效;
    struct tagPOINT *ru;      // 右上一点

    int b_rd;                 // 右下一点是否存在或者有效，-1：不存在;0：无效;1：有效;
    struct tagPOINT *rd;      // 右下一点
} POINT, *PPOINT;

typedef struct tagEPOINT
{
    POINT point;                  // 点数据

    int   n_crossover;            // 连续于该点的变化数目

    struct tagEPOINT* prev;       // 端点集合中的前一点
    struct tagEPOINT* next;       // 端点集合中的后一点

} EPOINT, *PEPOINT;

typedef struct tagTPOINT
{
    PEPOINT ppoint;                  // 点数据

    struct tagTPOINT* prev;       // 端点集合中的前一点
    struct tagTPOINT* next;       // 端点集合中的后一点

} TPOINT, *PTPOINT;
typedef struct tagTPOINTS // 变化的端点集合
{
    int     iTotal;  // 总点数
    PTPOINT pPoints; // TPOINT类型的双向列表头指针
    DELTAS  deltas;  // 该端点集合所代表的变化
} TPOINTS, PTPOINTS;


typedef struct tagTSTHPSV // TheSameThingPointSetOfVision 视觉同一物点集,亦即视觉变化
{
    TPOINTS    tps1;      // 端点集1，其变化与tps2相反
    TPOINTS    tps2;      // 端点集2，其变化与tps1相反
    int        iTotal;    // 总点数
    int        iEPTotal;  // 总边缘点数
    int        iMinIndex; // 最小物质元索引号
    int        iMaxIndex; // 最大物质元索引号
    PEPOINT    pEPS;      // 边缘点集，包括所有端点，端点是特殊的边缘点，该变量是指向PPOINT图的结点
} TSTHPSV, *PTSTHPSV;

typedef struct tagABSTRACT // 更抽象同一物点集列表元素
{
    void * pabs;
    struct tagABSTRACT *prev;
    struct tagABSTRACT *next;
} ABSTRACT, *PABSTRACT;

typedef struct tagCTSTHPSV // 视觉同一物点集 列表元素
{
    PTSTHPSV  ptsth;            // 视觉同一物点集数据
    struct tagCTSTHPSV* prev; // 前一视觉同一物点集
    struct tagCTSTHPSV* next; // 后一视觉同一物点集
    PABSTRACT pabs;           // 更抽象同一物点集列表头指针
} CTSTHPSV, *PCTSTHPSV;

extern PCTSTHPSV g_tsthpsv_list; // 视觉同一物点集列表

// 计算两个变化（A，B）之间的关系,如果B==A，则返回0；如果B完全属于A，则返回1；否则返回-1
int DeltasRelation(DELTAS &A, DELTAS &B);

// 由两个位置上连续的点，构建一个视觉同一物点集
int CreateTSTHPSV(CVisionMatterElementSet &vmes,POINT &point1, POINT &point2,PTSTHPSV *ppTSTHPSV);

// 判断某个点是否已存在于视觉同一物中
bool IsIn(CVisionMatterElementSet &vmes,TSTHPSV &tsth, POINT &point,PEPOINT *pret);

// 遍历某个视觉物质元点集，以发现一级视觉同一物点集列表
int IterateVMES(CVisionMatterElementSet &vmes);

// 查看pCurCTSTHPSV上点pep的所有变化，统计这些变化中与pTSTHPSV中的变化相连续的数目
int GetUnbrokenNubmer(CVisionMatterElementSet &vmes, CTSTHPSV *pCurCTSTHPSV, PTSTHPSV pTSTHPSV,PEPOINT pep);

// 尝试将同一物pTSTHPSV吸收进入pCurCTSTHPSV
int TryToAbsorb(CTSTHPSV *pCurCTSTHPSV, PTSTHPSV pTSTHPSV);

// 向 视觉同一物点集列表（g_tsthpsv_list）中提交视觉同一物点集
int UploadTSTHPSV(CVisionMatterElementSet &vmes,PTSTHPSV pTSTHPSV);

#endif // THESCT_H
